package com.bigfans.cartservice.api.interceptor;

import com.bigfans.Constants;
import com.bigfans.framework.Applications;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.CurrentUserFactory;
import com.bigfans.framework.annotations.NeedLogin;
import com.bigfans.framework.exception.UserNotLoginException;
import com.bigfans.framework.utils.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author lichong
 * @version V1.0
 * @Title:
 * @Description: 登录拦截器, 如果被请求的方法上有@NeedLogin注解,那么就会做登录验证
 * @date 2016年1月27日 上午8:48:52
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader(Constants.TOKEN.HEADER_KEY_NAME);
        CurrentUser currentUser = CurrentUserFactory.getCurrentUser(token, Constants.TOKEN.JWT_SECURITY_KEY);
        Applications.setCurrentUser(currentUser);
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        NeedLogin loginAnno = handlerMethod.getMethodAnnotation(NeedLogin.class);
        // 当前请求不需要登录
        if (loginAnno == null) {
            return true;
        }
        // 如果当前用户已经登录
        if (currentUser.isLoggedIn()) {
            return this.checkAccess(loginAnno, currentUser);
        } else {
            throw new UserNotLoginException();
        }
    }

    protected boolean checkAccess(NeedLogin loginAnno, CurrentUser currentUser) {
        String[] roles = loginAnno.roles();
        if (roles == null || roles.length == 0) {
            return true;
        }
        List<String> userRoles = currentUser.getRoles();
        if (CollectionUtils.isNotEmpty(currentUser.getRoles())) {
            for (String role : roles) {
                if (userRoles.contains(role)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        Applications.clearCurrentUser();
    }

}
